package ginx

import (
	"errors"
	"net/http"

	"gitee.com/chewel/hermes/pkg/errs"
	"github.com/gin-gonic/gin"
)

type Result[T any] struct {
	Data    T      `json:"data"`
	Msg     string `json:"msg"`
	Success bool   `json:"success"`
}

func NewSuccessResult[T any](data T) Result[T] {
	return NewResult[T](data, "", true)
}

func NewFailResult[T any](msg string) Result[T] {
	var zero T
	return NewResult[T](zero, msg, false)
}

func NewResult[T any](data T, msg string, success bool) Result[T] {
	return Result[T]{
		Data:    data,
		Msg:     msg,
		Success: success,
	}
}

func OK[T any](c *gin.Context, data T) {
	c.JSON(http.StatusOK, NewSuccessResult(data))
}

func BadRequest(c *gin.Context, msg string) {
	c.AbortWithStatusJSON(http.StatusBadRequest, NewFailResult[any](msg))
}

func NotFound(c *gin.Context, msg string) {
	c.AbortWithStatusJSON(http.StatusNotFound, NewFailResult[any](msg))
}

func InternalServerError(c *gin.Context, msg string) {
	c.AbortWithStatusJSON(http.StatusInternalServerError, NewFailResult[any](msg))
}

func Unauthorized(c *gin.Context, msg string) {
	c.AbortWithStatusJSON(http.StatusUnauthorized, NewFailResult[any](msg))
}

func Forbidden(c *gin.Context, msg string) {
	c.AbortWithStatusJSON(http.StatusForbidden, NewFailResult[any](msg))
}

func Conflict(c *gin.Context, msg string) {
	c.AbortWithStatusJSON(http.StatusConflict, NewFailResult[any](msg))
}

func Error(c *gin.Context, err error) {
	var er errs.Error
	if errors.As(err, &er) {
		c.AbortWithStatusJSON(er.Code, NewFailResult[any](er.Message))
	} else {
		c.AbortWithStatusJSON(http.StatusInternalServerError, NewFailResult[any](err.Error()))
	}
}
